/*! Index Buffer Direct3D 11 Implementation

@author Sergio J. de los Santos
*/
#ifndef __CONSTANT_BUFFER_HEADER__
#define __CONSTANT_BUFFER_HEADER__


//! Constant Buffer interface
template<typename Params>
class ConstantBuffer 
{

protected:
	ID3D11Buffer*	m_pConstantBuffer;
	bool			m_bIsDirty;
	Params			m_paramsData;	


public:
	ConstantBuffer(ID3D11Device* pd3dDevice)
		:m_bIsDirty(true)
	{
		D3D11_BUFFER_DESC	desc;
		desc.ByteWidth				= sizeof(m_paramsData);
		desc.Usage					= D3D11_USAGE_DYNAMIC;
		desc.BindFlags				= D3D11_BIND_CONSTANT_BUFFER;
		desc.CPUAccessFlags			= D3D11_CPU_ACCESS_WRITE;
		desc.MiscFlags				= 0;

		HRESULT hr = pd3dDevice->CreateBuffer(&desc, NULL, &m_pConstantBuffer);

#ifdef DEBUG
		m_pConstantBuffer->SetPrivateData( WKPDID_D3DDebugObjectName, strlen("ConstantBuffer"), "ConstantBuffer" );
#endif // DEBUG
	}

	virtual ~ConstantBuffer()
	{
		_SAFE_RELEASE(m_pConstantBuffer);
	}

	uint32	GetSize() const					{ return sizeof(m_paramsData);	}
	Params*	GetPointerData()				{ return &m_paramsData;			}
	bool	IsDirty() const					{ return m_bIsDirty;			}

	void SetAsDirty(bool bState = true)		{ m_bIsDirty		= bState;	}

	void UpdateParams(const Params& p)		{ m_paramsData = p; m_bIsDirty = true;	}

	ID3D11Buffer*	GeConstantBuffer()		{ return m_pConstantBuffer;		}
	ID3D11Buffer**	GeConstantBuffers()		{ return &m_pConstantBuffer;	}

	void Upload(ID3D11DeviceContext* pd3dContext)
	{
		D3D11_MAPPED_SUBRESOURCE mappedResource;
		pd3dContext->Map(m_pConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
		memcpy(mappedResource.pData, &m_paramsData, sizeof(m_paramsData));
		pd3dContext->Unmap(m_pConstantBuffer, 0);
	}
};



#endif 